#include "stdafx.h"
#include "libraries.h"

#include "Application.h"
#include "GUI.h"
#include "CollapseGUIStyle.h"
#include "StateManager.h"
#include "Filesystem.h"

#include "States.h"
#include "Menus.h"
#include "Game.h"

using namespace Cvekas;

class Collapse : public Application
{
public:
	Collapse(HINSTANCE instance, const std::string& name, const std::string& log_filename)
		:
	Application(instance, name, log_filename), state_manager(STATE_COUNT, 0.4f)
	{
		Filesystem::init();
	}

	virtual ~Collapse() {}

	virtual void initVideoDevice()
	{
		settings->insert("video", VideoSettings());

		(*settings)["video"]["ScreenWidth"] = 1024;
		(*settings)["video"]["ScreenHeight"] = 768;
		(*settings)["video"]["VSync"] = false;
		(*settings)["video"]["Fullscreen"] = false;

		window = WindowPtr(new Window(instance, name));
		window->showCursor(false);
		video_device->init(window);
	}

	virtual void init()
	{
		sprite_batch = video_device->createSpriteBatch(main_renderer, 1024, 768, 0);
		
		font = BitmapFontPtr(new BitmapFont(sprite_batch, Filesystem::redirect("gputeks.fnt"), 1));
		
		CollapseGUIStylePtr gui_style(new CollapseGUIStyle(sprite_batch, texture_manager, font));
		GUIPtr gui(new GUI(gui_style, input));
		setGUI(gui);

		video_device->setClearColor(Color(255, 255, 255));

		// No background for now
		//background = texture_manager->loadTexture2D("background", Filesystem::redirect("background.png"));

		input->getMouse()->setVirtualResolution(1024, 768);

		main_menu = MainMenuPtr(new MainMenu(main_renderer, font));
		options_menu = OptionsMenuPtr(new OptionsMenu(main_renderer, font, gui_style));
		game = GamePtr(new Game(main_renderer, font, sprite_batch));

		state_manager.setState(MAIN_MENU, main_menu);
		state_manager.setState(OPTIONS, options_menu);
		state_manager.setState(GAME, game);

		state_manager.pushState(MAIN_MENU);
	}

	virtual bool update()
	{
		input->getMouse()->update();
		return state_manager.update();
	}

	virtual bool render()
	{
		bool exit;

		video_device->beginScene();

		exit = state_manager.render();

		gui->present();
		sprite_batch->present();
		main_renderer->render();

		video_device->endScene();

		main_renderer->endFrame();
		return exit;
	}

private:
	SpriteBatchPtr sprite_batch;
	BitmapFontPtr font;

	Texture2DPtr background;

	StateManager state_manager;
	MainMenuPtr main_menu;
	OptionsMenuPtr options_menu;
	GamePtr game;
};

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nShowCmd)
{
	try
	{
		Collapse collapse(hInstance, "Collapse", "Collapse.log");
		collapse.run();
	}
	catch (std::exception& e)
	{
		MessageBox(NULL, e.what(), "Fatal error", NULL);
	}
	return 0;
}
